﻿
namespace Huirui.Cavan.Presentation.Seedwork
{
    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Reflection;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.UI.WebControls;
    using Huirui.Cavan.Core.Attribute;
    using Huirui.Cavan.Core.Extension;

    public static class Ext
    {
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type from, object htmlAttributes)
        {
            IDictionary<string, object> dictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);

            string name = ExpressionHelper.GetExpressionText(expression);

            string fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

            if (null != dictionary && dictionary.ContainsKey("id"))
            {
                object id = string.Empty;
                dictionary.TryGetValue("id", out id);
                return ListControlUtil.GenerateHtml(fullHtmlFieldName, id.ToString(), from, dictionary, metadata.Model);
            }
            return ListControlUtil.GenerateHtml(fullHtmlFieldName, fullHtmlFieldName, from, dictionary, metadata.Model);
        }

        public static string GetEnumDescription(Type enumType, string value)
        {
            foreach (ListItem li in ListControlUtil.ConvertEnumToListItems(enumType))
            {
                if (li.Value == value)
                {
                    return li.Text;
                }
            }
            return string.Empty;
        }
    }

    public static class ListControlUtil
    {
        public static MvcHtmlString GenerateHtml(string fullHtmlFieldName, string id, Type from, IDictionary<string, object> dictionary, object stateValue)
        {
            TagBuilder select = new TagBuilder("select");
            select.GenerateId(id);
            select.MergeAttribute("name", fullHtmlFieldName, true);
            string currentValue = string.Empty;
            if (stateValue != null)
                currentValue = GetValueFromName(from, stateValue.ToString());
            foreach (var item in ConvertEnumToListItems(from, dictionary))
            {
                select.InnerHtml = select.InnerHtml + GenerateOptionHtml(item.Text, item.Value, item.Value == currentValue);
            }

            return new MvcHtmlString(select.ToString());
        }

        private static string GenerateOptionHtml(string text, string value, bool isSelected)
        {
            StringBuilder sb = new StringBuilder();
            TagBuilder option = new TagBuilder("option");
            option.SetInnerText(text);
            option.MergeAttribute("value", value);
            if (isSelected)
            {
                option.MergeAttribute("selected", "selected");
            }
            sb.AppendLine(option.ToString());

            return sb.ToString();
        }

        public static List<ListItem> ConvertEnumToListItems(Type EnumType, IDictionary<string, object> dictionary = null)
        {
            if (EnumType.IsEnum == false) { return null; }
            List<ListItem> ListResult = new List<ListItem>();
            Type TypeDescription = typeof(NameAttribute);
            FieldInfo[] Fields = EnumType.GetFields();
            string StrText = string.Empty;
            string StrValue = string.Empty;
            foreach (FieldInfo Field in Fields)
            {
                if (Field.IsSpecialName) continue;
                StrValue = Field.GetRawConstantValue().ToString();
                object[] arr = Field.GetCustomAttributes(TypeDescription, true);
                if (arr.Length > 0)
                {
                    StrText = (arr[0] as NameAttribute).Name;
                }
                else
                {
                    StrText = Field.Name;
                }

                ListResult.Add(new ListItem(StrText, StrValue));
            }
            if (dictionary.IsNotNull())
            {
                if (dictionary.ContainsKey("defaultText"))
                {
                    object defaultText;
                    object defaultValue;
                    dictionary.TryGetValue("defaultText", out defaultText);
                    dictionary.TryGetValue("defaultValue", out defaultValue);
                    ListResult.Insert(0, new ListItem(defaultText.ToString(), defaultValue.ToString()));
                }
            }

            return ListResult;
        }

        public static string GetValueFromName(Type EnumType, string name)
        {
            FieldInfo[] Fields = EnumType.GetFields();
            foreach (FieldInfo Field in Fields)
            {
                if (Field.IsSpecialName) continue;
                if (Enum.Parse(EnumType,Field.Name).GetHashCode().ToString().Equals(name))
                {
                    return Field.GetRawConstantValue().ToString();
                }
            }

            return string.Empty;
        }
    }


}
